#pragma once

#include "BindingList.h"
#include "IDependencyBinding.h"
#include "DependencyBinding.h"

#include <typeinfo>

using namespace std;

class DependencyContainer
{
public:
	DependencyContainer();
	~DependencyContainer();

	template <class Source>
	DependencyBinding<Source>* Bind();

	template <class Type>
	vector<IDependencyBinding*> GetBindings();

	template<class Interface>
	DependencyContainer* Get();

	template<class Type>
	DependencyContainer* For();

	IDependencyBinding* Out();
private:
	BindingList* bindingList;
	vector<IDependencyBinding*> gotDependenties;
	IDependencyBinding* gotDependienty;
};

template <class Source>
DependencyBinding<Source>* DependencyContainer::Bind()
{
	DependencyBinding<Source>* binding =  new DependencyBinding<Source>();
	this->bindingList->Add(binding);
	return binding;

}

template <class Type>
vector<IDependencyBinding*> DependencyContainer::GetBindings()
{
	return this->bindingList->GetBindings<Type>();
}

template<class Interface>
DependencyContainer*  DependencyContainer::Get()
{
	vector<IDependencyBinding*>::iterator it;

	for(it=this->gotDependenties.begin();it!=this->gotDependenties.end();++it)
	{
		if ((*it)->IsBind<Interface>())
		{
			this->gotDependienty = (*it);
			return this;
		}
	}

	throw new exception("Dependency not found");
}

template<class Type>
DependencyContainer*  DependencyContainer::For()
{
	this->gotDependenties.clear();
	this->gotDependenties = this->bindingList->GetBindings<Type>();	
	return this;
}

